package com.iris.live.services.common;

import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Time;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;

/**
 * Created by ThinkPad on 2016/9/23.
 */
public class DateFormatUtils {
    public static  final String TIME_FORMAT_STR_YYYY_MM_DD ="yyyy-MM-dd";
    public static  final String TIME_FORMAT_STR_YYYY_MM_DD_HH_MM_SS ="yyyy-MM-dd HH:mm:ss";
    public static  final String TIME_FORMAT_STR_YYYYMMDD ="yyyyMMdd";
    public static  final String TIME_FORMAT_STR_YYYY_MM ="yyyy-MM";
    public static  final String TIME_FORMAT_STR_YYYYMM ="yyyyMM";
    private static Logger logger = LoggerFactory.getLogger(DateFormatUtils.class);

    /**
     * 为日期数据添加指分隔符，比如20170101->2017-01-01
     * @param date
     * @param seperator
     * @return
     */
    public static String addSeperator(String date, String seperator){
        if(StringUtils.isNullOrBlank(date)) return date;

        if(date.length() == 8){
            return date.substring(0, 4) + seperator + date.substring(4, 6) + seperator + date.substring(6, 8);
        }else if(date.length() == 10) {
            return date.substring(0, 4) + seperator + date.substring(5, 7) + seperator + date.substring(8, 10);
        }else{
            throw new IllegalArgumentException("无效日期长度，日期参数长度为8位或者10位。");
        }
    }

    /**
     * 返回指定格式、指定日期的date类型
     */
    public static Date getFormatDate(String format, Date date) {
        Date dt = null;
        try {
            String dateStr = new SimpleDateFormat(format).format(date);
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            dt = sdf.parse(dateStr);

        } catch (Exception e) {
            logger.error("日期格式化异常。", e);
        }
        return dt;
    }

    /**
     * String 转 date
     */
    public static Date getFormatDate(String date,String format) {
        Date dt = null;

          try {
              SimpleDateFormat sdf = new SimpleDateFormat(format);
              dt = sdf.parse(date);
          }
          catch (Exception e) {
              logger.error("日期格式化异常。", e);
          }
            return dt;
    }

    /**
     * date转string
     */
    public static String getFormatDateToString(Date date,String format)  throws ParseException{
        String dt = null;
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            dt = sdf.format(date);
            return dt;
    }

    /**
     * 返回指定格式、日期的时间戳
     */
    public static Timestamp getFormatTimestamp(String format, Date date) {
        Timestamp tsTime = Timestamp.valueOf(new SimpleDateFormat(format).format(date));
        return tsTime;
    }

    /**
     * 将string日期转换成sql date
     */
    public static java.sql.Date parseStrToSqlDate(String str) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = sdf.parse(str);
        java.sql.Date sqldate = new java.sql.Date(DateFormatUtils.getFormatDate("yyyy-MM-dd", dt).getTime());
        return sqldate;
    }

    /**
     * 将string日期转换成sql date
     */
    public static java.sql.Date parseStrToSqlDate(Date date) throws ParseException {
        Date dt = date;
        java.sql.Date sqldate = new java.sql.Date(DateFormatUtils.getFormatDate("yyyy-MM-dd", dt).getTime());
        return sqldate;
    }

    /**
     * 将string日期转换成sql date
     */
    public static Time parseStrToSqlTime(String str) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        Date dt = sdf.parse(str);
        Time sqldate = new Time(DateFormatUtils.getFormatDate("HH:mm:ss", dt).getTime());
        return sqldate;
    }

    /**
     * 将string转成Timestamp
     */
    public static Timestamp parseStrToTimestamp(String str) {
        Timestamp ts = Timestamp.valueOf(str);
        return ts;
    }

    /**
     * 时间是否未进店
     * @param startTime
     * @param endTime
     * @return
     */
    public static boolean isNoStore(Time startTime,Time endTime){
        if(null == startTime || null == endTime ){
            return true;
        }

        DateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        String start = sdf.format(startTime);
        String end = sdf.format(endTime);

        if("03:00:00".equals(start) && "03:01:00".equals(end)) {
            return true;
        }
        if("03:00:00".equals(start) && "03:01:00".equals(end)) {
            return true;
        }
        if("00:00:00".equals(start) && "00:01:00".equals(end)) {
            return true;
        }
        if("01:00:00".equals(start) && "01:01:00".equals(end)) {
            return true;
        }
        return false;
    }
    /**
     * 时间是否未进店
     * @param startTime
     * @return
     */
    public static boolean isNoStore(Time startTime ){
        if(null == startTime   ){
            return true;
        }

        DateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        String start = sdf.format(startTime);

        if("03:00:00".equals(start) ) {
            return true;
        }
        if("00:00:00".equals(start) ) {
            return true;
        }
        if("01:00:00".equals(start) ) {
            return true;
        }
        return false;
    }

    /**
     * 按天分割时间段 获取日期字符串
     */
    public static List<String> splitDate(String start,String end ) throws ParseException {
        List<String> dateList = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        long sdt = sdf.parse(start).getTime();
        long edt = sdf.parse(end).getTime();
        while(sdt<=edt){
            dateList.add(sdf.format(new Date(edt)));
            edt-=24 * 60 * 60 * 1000;
        }
        return dateList;
    }

    /**
     *获取时间的前i天
     * @param str
     * @param i
     * @return
     * @throws ParseException
     */
    public static java.sql.Date subStringToDate(String str,Integer i) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date dt = sdf.parse(str);
        java.sql.Date sqldate = new java.sql.Date(DateFormatUtils.getFormatDate("yyyy-MM-dd", dt).getTime()-i*24 * 60 * 60 * 1000);
        return sqldate;
    }

    /**
     * 获取两个字符串时间相隔的天数
     * @param startTime
     * @param endTime
     * @return
     * @throws ParseException
     */
    public static Integer betweenDay(String startTime,String endTime) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        long start = sdf.parse(startTime).getTime();
        long end = sdf.parse(endTime).getTime();
        long num = (end-start)/(24 * 60 * 60 * 1000);
        return Integer.parseInt(String.valueOf(num));
    }

    /**
     * 获取两个时间间隔分钟
     * @param startTime
     * @param endTime
     * @return
     * @throws ParseException
     */
    public static Integer betweenMinutes(Date startTime,Date endTime) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        long start = startTime.getTime();
        long end = endTime.getTime();
        long num = (end-start)/( 60 * 1000);
        return Integer.parseInt(String.valueOf(num));
    }

    /**
     * 获取录入月份的第一天
     * @param day
     * @return
     */
    public static Date getDateByMonthFirstDay(Date day) throws ParseException{
        Calendar calendar=new GregorianCalendar();
        SimpleDateFormat sdf=new SimpleDateFormat(DateFormatUtils.TIME_FORMAT_STR_YYYY_MM_DD);
        calendar.setTime(getFormatDate(getFormatDateToString(day,DateFormatUtils.TIME_FORMAT_STR_YYYY_MM),DateFormatUtils.TIME_FORMAT_STR_YYYY_MM));
        calendar.add(calendar.DATE, 0);//因为格式化时默认了DATE为本月第一天所以此处为0
        return getFormatDate(sdf.format(calendar.getTime()),DateFormatUtils.TIME_FORMAT_STR_YYYY_MM_DD);
    }

    /**
     * 获取录入月份的最后一天
     * @param day
     * @return
     */
    public static Date getDateByMonthLastDay(Date day)  throws ParseException{
        Calendar calendar=new GregorianCalendar();
        SimpleDateFormat sdf=new SimpleDateFormat(DateFormatUtils.TIME_FORMAT_STR_YYYY_MM_DD);
        calendar.setTime(getFormatDate(getFormatDateToString(day,DateFormatUtils.TIME_FORMAT_STR_YYYY_MM),DateFormatUtils.TIME_FORMAT_STR_YYYY_MM));
        calendar.roll(calendar.DATE, -1);//api解释roll()：向指定日历字段添加指定（有符号的）时间量，不更改更大的字段
        return getFormatDate(sdf.format(calendar.getTime()),DateFormatUtils.TIME_FORMAT_STR_YYYY_MM_DD);
    }

    /**
     * 获取系统当前时间
     * @return
     */
    public static long getCurrentTime(){
        return System.currentTimeMillis();
    }

    public static String getFirstDayOfMonth(String year, String month){
        return year + "-" + (month.length() == 1 ? "0" + month : month) + "-01";
    }

    public static String getEndDayOfMonth(String year, String month){
        Calendar cale = Calendar.getInstance();
        cale.set(Integer.parseInt(year), Integer.parseInt(month), 1);
        cale.add(Calendar.DAY_OF_MONTH, -1);

        try {
            return getFormatDateToString(cale.getTime(), TIME_FORMAT_STR_YYYY_MM_DD);
        }catch(Exception exc){
            logger.warn("Exception raised.", exc);
            return null;
        }
    }

    /**
     * 获取系统时间的上个月
     * @return
     */
    public static String getLastMonth(int month){
        SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT_STR_YYYYMM);
        Date date = new Date();
       return sdf.format(getMonthDate(date,month));
    }

    /**
     * 获取系统时间的前N个月前的第一天
     * @return
     */
    public static String getBeforeMonthFirstDay(int month,int formatType){
        SimpleDateFormat sdf = null;
        String result = null;
        Date date = new Date();
        try{
            switch (formatType){
                case 1:
                    sdf = new SimpleDateFormat(TIME_FORMAT_STR_YYYY_MM_DD_HH_MM_SS);
                    result = sdf.format(getDateByMonthFirstDay(getMonthDate(date,month)));
                    break;
                case 2:
                    sdf = new SimpleDateFormat(TIME_FORMAT_STR_YYYY_MM_DD);
                    result = sdf.format(getDateByMonthFirstDay(getMonthDate(date,month)))+ " 23:59:59" ;
                    break;
                case 3:
                    sdf = new SimpleDateFormat(TIME_FORMAT_STR_YYYY_MM_DD);
                    result = sdf.format(getDateByMonthFirstDay(getMonthDate(date,month)));
                    break;

            }
        }catch (Exception e){
            return result;
        }
        return result;
    }

    /**
     * 获取系统时间的前N个月前的最后一天
     * @return
     */
    public static String getBeforeMonthLastDay(int month,int formatType){
        SimpleDateFormat sdf = null;
        String result = null;
        Date date = new Date();
        try{
            switch (formatType){
                case 1:
                    sdf = new SimpleDateFormat(TIME_FORMAT_STR_YYYY_MM_DD_HH_MM_SS);
                    result = sdf.format(getDateByMonthLastDay(getMonthDate(date,month)));
                    break;
                case 2:
                    sdf = new SimpleDateFormat(TIME_FORMAT_STR_YYYY_MM_DD);
                    result = sdf.format(getDateByMonthLastDay(getMonthDate(date,month)))+ " 23:59:59" ;
                    break;
                case 3:
                    sdf = new SimpleDateFormat(TIME_FORMAT_STR_YYYY_MM_DD);
                    result = sdf.format(getDateByMonthLastDay(getMonthDate(date,month)));
                    break;
            }
        }catch (Exception e){
            return result;
        }
        return result;
    }
    /**
     * 获取前一个月的第一天和最后一天
     * @return
     */
    public static List getAfterDate(){
        LocalDate now = LocalDate.now();
        LocalDate start = LocalDate.of(now.getYear(),now.getMonth(),1);
        LocalDate end = start.plusDays(-1L);
        start = start.plusMonths(-1L);
        List list = Lists.newArrayList();
        list.add(start.toString());
        list.add(end.toString());
        return list;
    }


    private static Date getMonthDate(Date date,int month) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.MONTH, -month);
        return cal.getTime();
    }

    public static  void main(String[] args) throws Exception {
        System.out.println(getBeforeMonthFirstDay(3,1));
        System.out.println(getBeforeMonthFirstDay(3,2));
        System.out.println(getBeforeMonthLastDay(1,1));
        System.out.println(getBeforeMonthLastDay(1,2));
    }


}
